<?php

namespace app\service;

use app\common\controller\AppCommon;
use think\Db;

class CurdService
{

    //检测表是否存在数据库中
    public static function check_table_exist($tableName)
    {
        $prefix = config('database.prefix');
        if (stripos($tableName, $prefix) !== 0) {
            $tableName = $prefix . $tableName;
        }
        $sql = "SHOW TABLES LIKE '$tableName'";
        $res = Db::query($sql);
        return $res;
    }

    //查询表信息
    public static function get_table_info($tableName)
    {
        $prefix = config('database.prefix');
        if (stripos($tableName, $prefix) !== 0) {
            $tableName = $prefix . $tableName;
        }
        $sql = "SHOW FULL COLUMNS FROM $tableName";
        $res = Db::query($sql);
        return $res;
    }

    //字段处理
    public static function get_table_fields($tableInfo)
    {
        $getLength = function ($type) {
            if (preg_match('/\((\d+)\)/', $type, $matches)) {
                return $matches[1];
            } else {
                return '';
            }
        };

        $auto_id = 'id';
        $fields = [];
        $baseData = [];
        foreach ($tableInfo as $v) {
            if ($v['Extra'] == 'auto_increment') {
                $auto_id = $v['Field'];
            }
            $auto_id != $v['Field'] && $baseData[] = $v['Field'];
            $type = 'str';
            switch (true) {
                case stripos($v['Type'], 'mediumint') === 0:
                case stripos($v['Type'], 'tinyint') === 0:
                case stripos($v['Type'], 'int') === 0:
                    $type = 'int';
                    break;
                case stripos($v['Type'], 'longtext') === 0:
                case stripos($v['Type'], 'text') === 0:
                    $type = 'text';
                    break;
                case stripos($v['Type'], 'datetime') === 0:
                    $type = 'datetime';
                    break;
                case stripos($v['Type'], 'date') === 0:
                    $type = 'date';
                    break;
                case stripos($v['Type'], 'time') === 0:
                    $type = 'time';
                    break;
                case stripos($v['Type'], 'float') === 0:
                case stripos($v['Type'], 'double') === 0:
                case stripos($v['Type'], 'decimal') === 0:
                    $type = 'float';
                    break;
                case stripos($v['Type'], 'char') === 0:
                    $type = 'str_1';
                    break;
                case stripos($v['Type'], 'varchar') === 0:
                    $type = 'str_3';
                    break;
            }
            $comment = str_replace(':', "：", $v['Comment']);

            $commentArr = explode('：', $comment, 2);

            $fields[] = [
                'name' => $v['Field'],
                'data_type' => $type,
                'comment' => !empty($commentArr[0]) ? $commentArr[0] : ($commentArr[1] ?? $v['Comment']),
                'default' => $v['Default'],
                'not_null' => $v['Null'] == 'NO' ? 1 : 0,
                'length' => $getLength($v['Type']),
                'is_auto' => $v['Extra'] == 'auto_increment' ? 1 : 0,
                'is_key' => !empty($v['Key']) ? 1 : 0,
            ];
        }
        return [
            'auto_id' => $auto_id,
            'base_data' => $baseData,
            'fields' => $fields,
        ];
    }


    public function run($tableName)
    {
        $prefix = config('database.prefix');
        if (stripos($tableName, $prefix) === 0) {
            //去掉前缀
            $tableName = substr($tableName, strlen($prefix));
        }
        $tableInfo = self::get_table_info($tableName);
        //print_r($tableInfo);exit();
        $getFields = self::get_table_fields($tableInfo);

        $auto_id = $getFields['auto_id'];
        $baseData = $getFields['base_data'];
        $fields = $getFields['fields'];

        //print_r($fields);exit();
        //搜索条件
        $searchWhereStr = '';
        $searchWhere = [];


        $form = [];
        foreach ($baseData as $k => $v) {
            $form[$v] = "\$param['$v']";
        }
        $formData = [];
        foreach ($form as $k => $v) {
            $formData[] = "'$k' => $v ?? '',";
        }
        //对齐一下
        $formData = implode("\n            ", $formData);
        //规则验证

        $ruleStr = '';
        foreach ($fields as $k => $v) {
            if ($v['data_type'] == 'int' && !empty($v['is_key'])) {
                continue;
            }
            $itemRule = '';
            $itemType = 'empty';
            $itemMsg = $v['name'] . '有误';
            if (!empty($v['not_null'])) {
                switch ($v['data_type']) {
                    case 'str':
                    case 'str_1':
                    case 'str_3':
                        //$searchWhere[]= " \$where['{$v['name']}'] = ['like','%'.\$keyword.'%'];\n        ";
                        $searchWhere[] = $v['name'];
                        $itemType = 'length';
                        $itemRule = '1,' . $v['length'];
                        $itemMsg = ($v['comment'] ?? $v['name']) . '应在1~' . $v['length'] . "之间";
                        break;
                    case 'int':
                    case 'text':
                        $itemType = 'empty';
                        $itemMsg = ($v['comment'] ?? $v['name']) . '不能为空';
                        break;
                }
                $ruleStr .= "['type' => '$itemType', 'key' => '{$v['name']}', 'rule' => '$itemRule', 'msg' => '$itemMsg',],\n            ";
            }
        }

        //规则验证
        if (!empty($ruleStr)) {
            $ruleStrTpl = <<<doc
//表单验证
        \$rule = [
            $ruleStr
        ];
        \$check = check_param(\$param, \$rule);
         if (\$check['code'] <> 0) {
             data_return(\$check['msg'], \$check['code']);
         }
doc;
        }
        //条件查询
        if (!empty($searchWhere)) {
            $str = join('|', $searchWhere);
            $searchWhereStr .= " \$where['$str'] = ['like','%'.\$keyword.'%'];\n        ";
        }

        //表名转类名
        $className = implode('', array_map('ucfirst', explode('_', $tableName)));
        $tplClass = <<<doc
<?php

namespace app\admin\controller\auto;

use app\admin\controller\com\Admin;
use app\common\controller\AppCommon;
use app\service\Page;

class $className extends Admin
{
    //详情
    function data_get()
    {
        \$id = input('id',0,'intval');
        if (!empty(\$id)) {
            \$this->assign('data', AppCommon::data_get('$tableName', ['$auto_id'=> \$id]));
        }
        return \$this->fetch();
    }
    
    //列表
    function data_list()
    {
        \$where = [];
       
        \$orderBy = '$auto_id desc';
        \$param = request()->param();
        \$keyword = \$param['keyword']??'';
       
        $searchWhereStr
        \$page = !empty(\$param['page']) ? intval(\$param['page']) : 1;
        \$pageSize = 10;
        \$total = AppCommon::data_count('$tableName', \$where);
        \$data = AppCommon::data_list('$tableName', \$where, \$page . ',' . \$pageSize, '*', \$orderBy);
        \$this->assign('page', Page::set(\$data, \$pageSize, \$page, \$total, \$param, url()));
        \$this->assign('data', \$data);
        return \$this->fetch();
    }
    
    //删除数据
    function data_del()
    {
        \$id = input('id',0,'intval');
        if (empty(\$id)) {
            data_return('请选择要删除的数据',-1);
        }
        \$data = AppCommon::data_get('$tableName', ['$auto_id'=> \$id]);
        if (empty(\$data)) {
            data_return('数据不存在',-1);
        }
        if (AppCommon::data_del('$tableName', ['$auto_id'=> \$id])) {
            data_return('删除成功');
        }
        data_return('删除失败',-1);
    }
    
    //添加数据
    function data_add()
    {
        \$param = input('post.');
        \$id = input('id', 0, 'intval');
        
        $ruleStrTpl;
        
        
        \$data = array (
            $formData
        );
        if (!empty(\$id)) {

            \$res = AppCommon::data_update('$tableName', ['$auto_id' => intval(\$id)], \$data);
        } else {
            
            \$res = AppCommon::data_add('$tableName', \$data);
        }

        data_return('操作完成', 0, [
            'res' => \$res
        ]);
    }
    
}
doc;

        file_put_contents(APP_PATH . 'admin/controller/auto/' . $className . '.php', $tplClass);

    }


}